package com.minivision.fdiot.common.bus;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.stream.binding.BinderAwareChannelResolver;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.minivision.bus.event.RemoteBusEvent;

import lombok.extern.slf4j.Slf4j;

/**
 * Spring Cloud Bus消息发布器
 * @author hughzhao
 * @2018年3月1日
 */
@Component
@Slf4j
public class BusPublisher {
  
  @Autowired
  private ConfigurableApplicationContext context;
  
  @Autowired
  private BinderAwareChannelResolver resolver;
  
  @Autowired
  private ObjectMapper mapper;

  @Value("${mqtt.cloud.push}")
  private boolean needPush;
  
  /**
   * 广播消息
   * @param message
   * @throws Exception
   */
  public void broadcast(RemoteMessage<?> message) throws Exception {
    this.publish(message, null);
  }
  
  /**
   * 向某个destination发布消息
   * @param message
   * @param destination
   * @throws Exception
   */
  public void publish(RemoteMessage<?> message, String destination) throws Exception {
    if(needPush){
      String msgJson = null;
      if (message.getData() instanceof String) {
        msgJson = (String) message.getData();
      } else {
        msgJson = mapper.writeValueAsString(message.getData());
      }

      RemoteBusEvent busEvent = new RemoteBusEvent(context.getId(), message.getType(), msgJson);
      //单播消息
      if (StringUtils.hasText(destination)) {
        resolver.resolveDestination(destination).send(MessageBuilder.withPayload(busEvent).build());
      } else {//广播消息
        context.publishEvent(busEvent);
      }

      log.info("send device message to mq, message type:{}, destination:{}", message.getType(), destination);
    }
  }

}
